import 'package:dio/dio.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_base_framework/base_framework_export.dart';
import 'package:flutter_common_utils/common_utils_export.dart';
import 'package:flutter_refresh/flutter_refresh_export.dart';
import 'package:flutter_base_app/utils/http/http_error.dart';
import 'package:flutter_base_app/widgets/dialog/base/app_toast.dart';
import 'package:flutter_base_app/widgets/dialog/base/loading_dialog.dart';
import 'package:flutter_http_utils/flutter_http_utils.dart';

import 'http_code.dart';

class HttpUiHandler extends AbsHttpUiHandler {
  @override
  CancelToken? cancelToken;
  String tagKey = "";
  BuildContext? context;
  bool isCompleted = false;

  //是否错误的时候toast提示,只有Http错误的时候
  bool isErrorToastShow = true;

  /// 请求成功，但是接口Code错误的时候是否内部处理错误状态
  /// 默认为走错误方法
  /// 一般用于布局切换和显示toast
  bool isDataErrorToastShow = true;

  //是否显示对话框
  bool isShowLoading;

  //对话框是否可以取消
  bool isCancelable;

  //对话框提示的文本
  String? hint;

  //刷新和分页控制器
  AppRefreshController? refreshController;

  //布局切换的控制器
  LoadStateController? loadStateController;

  //控制加载
  LoadingController? _loadingController;

  //分页
  PageHelper? pageHelper;

  //开始超时,防止对话框不会消失
  Job? _jobTimeOut;

  bool _isSuccess = false;

  HttpUiHandler.get({
    BaseViewModel? vm,
    dynamic tag,
    CancelToken? token,
    this.refreshController,
    this.loadStateController,
    this.pageHelper,
    this.isErrorToastShow = true,
    this.hint,
    this.isShowLoading = true,
    this.isCancelable = true,
  }) {
    if (tag is BaseViewModel) {
      vm = tag;
    }
    context = vm?.context;
    refreshController = refreshController ?? vm?.refreshCtrl;
    loadStateController = loadStateController ?? vm?.loadStateCtrl;
    pageHelper = pageHelper ?? vm?.pageHelper;
    if (token != null) {
      cancelToken = token;
      if (vm != null) {
        CancelTokenManage.add(vm, token);
      } else if (tag != null) {
        CancelTokenManage.add(tag, token);
      }
    } else {
      if (vm != null) {
        cancelToken = CancelTokenManage.addAndCreate(vm);
        pageHelper ??= vm.pageHelper;
      } else if (tag != null) {
        cancelToken ??= CancelTokenManage.addAndCreate(tag);
      }
    }
  }

  ///设置默默调用，不提示
  void setNoTips() {
    isErrorToastShow = false;
    isShowLoading = false;
    isDataErrorToastShow = false;
  }

  /// 显示Toast
  void showErrorToast(String msg) {
    if (isErrorToastShow) {
      msg.toastInfo();
    }
  }

  //是否正在刷新或者加载更多数据
  bool isRefreshOrLoadMore() => refreshController?.isRefresh == true || refreshController?.isLoadMore == true;

  //是否布局切换正在加载
  bool isPageLoading() => loadStateController?.isLoading() == true;

  /// 显示 Loading 框
  void showLoadDialog() {
    if (!isRefreshOrLoadMore() && !isPageLoading()) {
      if (!isRefreshOrLoadMore() && !isPageLoading() && !isCompleted && isShowLoading) {
        if (_loadingController == null) {
          _loadingController = showLoadingDialog(msg: hint, clickMaskDismiss: isCancelable, backDismiss: isCancelable);
        } else {
          _loadingController?.updateMessage(hint);
        }
      }
    }
  }

  @override
  void start() {
    _isSuccess = false;
    isCompleted = false;
    if (loadStateController?.isLoadingCanShow() == true) {
      loadStateController?.showLoading();
    } else {
      showLoadDialog();
    }
  }

  @override
  void error(e, StackTrace stackTrace) {
    _isSuccess = false;
    if (e is DioException) {
      //被取消的请求不处理
      if (CancelToken.isCancel(e)) {
        return;
      }
    }
    final msg = HttpError.getError(e);
    loadStateController?.showRetry(data: ContextData(title: msg, errCode: 0));
    stackTrace.printStackTrace();
    LogUtils.e(e);
    showErrorToast(HttpError.getError(e));
  }

  @override
  void completed() {
    isCompleted = true;
    _loadingController?.dismiss();
    _loadingController = null;
    _jobTimeOut?.cancel();
    _jobTimeOut = null;
    //这个需要在回调代码执行完成后
    // LogUtils.e("completed refreshController = $refreshController,,,_isSuccess=${_isSuccess},,,${pageHelper?.isCanNextPage()}");
    if (_isSuccess) {
      refreshController?.finishRefresh(IndicatorResult.success, true);

      refreshController?.finishLoad(pageHelper?.isCanNextPage() != false ? IndicatorResult.success : IndicatorResult.noMore, true);
    } else {
      refreshController?.finishRefresh(IndicatorResult.fail, true);
      refreshController?.finishLoad(IndicatorResult.fail, true);
    }
  }

  @override
  void success(result) {
    _isSuccess = true;
    if (result is HttpResponse) {
      if (result.isSucceed) {
        loadStateController?.showContent();
      } else {
        loadStateController?.showRetry(data: ContextData(title: result.msg, errCode: result.code));
        if (result.code == HttpCodeApp.AUTH_ERROR || result.code == HttpCodeApp.NO_LOGIN) {
        } else {
          if (isDataErrorToastShow) {
            result.msg.toastInfo();
          }
        }
      }
    } else {
      loadStateController?.showContent();
    }
  }

  void updateLoadHint(String hint) {
    this.hint = hint;
    _loadingController?.updateMessage(hint);
  }

  /// 启动并且设置超时
  /// 开始超时,防止对话框不会消失
  void startTimeOut([int duration = 3000]) {
    start();
    if (!isShowLoading) return;
    if (_loadingController?.isExist() != true) return;

    _jobTimeOut?.cancel();
    _jobTimeOut = launchSJ((s, j) async {
      await j.delay(duration);
      completed();
    });
  }

  bool isShow() => _loadingController?.isExist() == true;
}
